home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / GDIDEMO.PAK / ARTY.CPP next >
C/C++ Source or Header  |  1997-05-06  |  10KB  |  382 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1995 by Borland International, All Rights Reserved
  4. //
  5. //   Arty demo window object
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #include <owl/dc.h>
  9. #include <owl/static.h>
  10. #include <stdlib.h>
  11. #include "arty.h"           // class definition for TArtyWindow
  12. #include "artypriv.h"       // internal component classes of TArtyWindow
  13.  
  14.  
  15. //---------- TList ----------------------------------------------
  16.  
  17. //
  18. // The low-level line draw routine
  19. //
  20. static void
  21. LineDraw(TDC& dc, int x1, int y1, int x2, int y2)
  22. {
  23.   dc.MoveTo(x1, y1);
  24.   dc.LineTo(x2, y2);
  25. }
  26.  
  27. //
  28. // Initialize the list-of-lines object 
  29. //
  30. TList::TList(int _max)
  31. {
  32.   MaxLines = min(_max, MaxLineCount);
  33.   CurrentLine = 1;
  34.   Xmax = 0;
  35.   Ymax = 0;
  36.   ColorDuration = MaxColorDuration;
  37.   IncrementCount = 0;
  38.   MaxDelta = 10;
  39.   PenColor = TColor(random(256), random(256), random(256));
  40. }
  41.  
  42. //
  43. // Keep X within range, and reverse Delta if necessary to do so
  44. //
  45. void
  46. TList::AdjustX(int& x, int& deltaX)
  47. {
  48.   int testX = x + deltaX;
  49.   if (testX < 1 || testX > Xmax) {
  50.     testX = x;
  51.     deltaX = -deltaX;
  52.   }
  53.   x = testX;
  54. }
  55.  
  56. //
  57. // Keep Y within range, and reverse Delta if necessary to do so
  58. //
  59. void
  60. TList::AdjustY(int& y, int& deltaY)
  61. {
  62.   int testY = y + deltaY;
  63.   if (testY < 1 || testY > Ymax) {
  64.     testY = y;
  65.     deltaY = -deltaY;
  66.   }
  67.   y = testY;
  68. }
  69.  
  70. //
  71. // Clear the array of lines
  72. //
  73. void
  74. TList::ResetLines() 
  75. {
  76.   int startX = Xmax / 2;
  77.   int startY = Ymax / 2;
  78.   for (int i = 0; i < MaxLines; i++) {
  79.     Line[i].LX1 = startX;
  80.     Line[i].LX2 = startX;
  81.     Line[i].LY1 = startY;
  82.     Line[i].LY2 = startY;
  83.     Line[i].Color = 0;
  84.   }
  85.   X1 = startX;
  86.   X2 = startX;
  87.   Y1 = startY;
  88.   Y2 = startY;
  89. }
  90.  
  91. //
  92. // Scale the old line coordinates to the new Xmax and Ymax coordinates.
  93. //  The new Xmax and new Ymax are passed in as parameters so we can
  94. //  calculate the scaling ratios.
  95. //
  96. void
  97. TList::ScaleTo(int newXmax, int newYmax)
  98. {
  99.   if (!Xmax || !Ymax) {    // at startup, Xmax and Ymax are zero
  100.     Xmax = newXmax;
  101.     Ymax = newYmax;
  102.     ResetLines();
  103.  
  104.   }
  105.   else {
  106.     X1 = int(long(X1)*newXmax / Xmax);
  107.     Y1 = int(long(Y1)*newYmax / Ymax);
  108.     X2 = int(long(X2)*newXmax / Xmax);
  109.     Y2 = int(long(Y2)*newYmax / Ymax);
  110.     for (int i = 0; i < MaxLines; i++) {
  111.       Line[i].LX1 = int(long(Line[i].LX1)*newXmax / Xmax);
  112.       Line[i].LX2 = int(long(Line[i].LX2)*newXmax / Xmax);
  113.       Line[i].LY1 = int(long(Line[i].LY1)*newYmax / Ymax);
  114.       Line[i].LY2 = int(long(Line[i].LY2)*newYmax / Ymax);
  115.     }
  116.   }
  117.   Xmax = newXmax;
  118.   Ymax = newYmax;
  119. }
  120.  
  121. // The high-level Draw method of the object.
  122. //
  123. void
  124. TList::DrawLine(TDC& dc, int index)
  125. {
  126.   TPen pen(Line[index].Color);
  127.   dc.SelectObject(pen);
  128.   LineDraw(dc, Line[index].LX1, Line[index].LY1, 
  129.                Line[index].LX2, Line[index].LY2);
  130.   dc.RestorePen();
  131. }
  132.  
  133. // The high-level draw which erases a line.
  134. //
  135. void TList::EraseLine(TDC& dc, int index)
  136. {
  137.   dc.SelectStockObject(BLACK_PEN);
  138.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  139.                Line[index].LX2, Line[index].LY2);
  140. }
  141.  
  142. //
  143. // Redraw all the lines in the array.
  144. //
  145. void
  146. TList::Redraw(TDC& dc)
  147. {
  148.   for (int i = 0; i < MaxLines; i++)
  149.     DrawLine(dc, i);
  150. }
  151.  
  152. //
  153. // Reset the color counter and pick a random color.
  154. //
  155. void
  156. TList::SelectNewColor()
  157. {
  158.   ColorDuration = MaxColorDuration;
  159.   PenColor = TColor(random(256), random(256), random(256));
  160. }
  161.  
  162. //
  163. // Pick random directional deltas and reset the delta counter.
  164. //
  165. void
  166. TList::SelectNewDeltaValues()
  167. {
  168.   DeltaX1 = random(MaxDelta) - MaxDelta/2;
  169.   DeltaX2 = random(MaxDelta) - MaxDelta/2;
  170.   DeltaY1 = random(MaxDelta) - MaxDelta/2;
  171.   DeltaY2 = random(MaxDelta) - MaxDelta/2;
  172.   IncrementCount = 2 * (1 + random(10));
  173. }
  174.  
  175. //
  176. // Process the movement of one line.
  177. //
  178. void
  179. TList::LineTick(TDC& dc)
  180. {
  181.   EraseLine(dc, CurrentLine);
  182.   if (ColorDuration < 0)
  183.     SelectNewColor();
  184.   if (!IncrementCount)
  185.     SelectNewDeltaValues();
  186.   AdjustX(X1, DeltaX1);
  187.   AdjustX(X2, DeltaX2);
  188.   AdjustY(Y1, DeltaY1);
  189.   AdjustY(Y2, DeltaY2);
  190.  
  191.   Line[CurrentLine].LX1 = X1;
  192.   Line[CurrentLine].LX2 = X2;
  193.   Line[CurrentLine].LY1 = Y1;
  194.   Line[CurrentLine].LY2 = Y2;
  195.   Line[CurrentLine].Color = PenColor;
  196.  
  197.   DrawLine(dc, CurrentLine);
  198.   CurrentLine++;
  199.   if (CurrentLine >= MaxLines)
  200.     CurrentLine = 1;
  201.   ColorDuration--;
  202.   IncrementCount--;
  203. }
  204.  
  205.  
  206. //------------ TQuadList ----------------------------------------
  207.  
  208. //
  209. // Draw the line and 3 reflections of it.
  210. //
  211. void
  212. TQuadList::DrawLine(TDC& dc, int index)
  213. {
  214.   TPen pen(Line[index].Color);
  215.   dc.SelectObject(pen);
  216.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  217.                Line[index].LX2, Line[index].LY2);
  218.   LineDraw(dc, Xmax - Line[index].LX1, Line[index].LY1,
  219.                Xmax - Line[index].LX2, Line[index].LY2);
  220.   LineDraw(dc, Line[index].LX1, Ymax - Line[index].LY1,
  221.                Line[index].LX2, Ymax - Line[index].LY2);
  222.   LineDraw(dc, Xmax - Line[index].LX1, Ymax - Line[index].LY1,
  223.                Xmax - Line[index].LX2, Ymax - Line[index].LY2);
  224.   dc.RestorePen();
  225. }
  226.  
  227. //
  228. // Erase the line and 3 reflections of it.
  229. //
  230. void
  231. TQuadList::EraseLine(TDC& dc, int index)
  232. {
  233.   dc.SelectStockObject(BLACK_PEN);
  234.   LineDraw(dc, Line[index].LX1, Line[index].LY1,
  235.                Line[index].LX2, Line[index].LY2);
  236.   LineDraw(dc, Xmax - Line[index].LX1, Line[index].LY1,
  237.                Xmax - Line[index].LX2, Line[index].LY2);
  238.   LineDraw(dc, Line[index].LX1, Ymax - Line[index].LY1,
  239.                Line[index].LX2, Ymax - Line[index].LY2);
  240.   LineDraw(dc, Xmax - Line[index].LX1, Ymax - Line[index].LY1,
  241.                Xmax - Line[index].LX2, Ymax - Line[index].LY2);
  242. }
  243.  
  244. //----------- TArtyWindow ------------------------------------------
  245.  
  246. DEFINE_RESPONSE_TABLE1(TArtyWindow, TBaseDemoWindow)
  247.   EV_WM_LBUTTONDOWN,
  248.   EV_WM_RBUTTONDOWN,
  249.   EV_WM_SIZE,
  250. END_RESPONSE_TABLE;
  251.  
  252. IMPLEMENT_CASTABLE1(TArtyWindow, TBaseDemoWindow);
  253.  
  254. //
  255. //
  256. //
  257. TArtyWindow::TArtyWindow() : TBaseDemoWindow()
  258. {
  259.   StaticControl = new TStatic(this, 100,
  260.     "Press Left Button to pause, Right Button to Clear",10,10,10,10,0);
  261.   Iconized = false;
  262.   TextHeight = 20;
  263.   Paused = false;
  264.  
  265.   // Initialize two line list objects:
  266.   //    BigLineList is the 4-reflection artwork that is displayed in
  267.   //    a full sized window.  Mouse clicks will pause or clear
  268.   //    the display, and the line list will be scaled to the
  269.   //    new window coordinates when the window is resized.
  270.   //
  271.   //    IconicLineList is a smaller list implementing a single-line
  272.   //    quark to display in the iconized window region.  Since
  273.   //    mouse clicks are not sent to iconized windows, the icon
  274.   //    cannot be paused or cleared, and since there is only one
  275.   //    icon window size, scaling the lines to new coordinates
  276.   //    has no visual effect.
  277.   //
  278.   //  The List pointer will be toggled between the two line list
  279.   //  objects: when the window is iconized, List will point to the
  280.   //  IconicLineList object.  When the window is restored to full
  281.   //  size, List will be made to point to the BigLineList object.
  282.   //  This is so the window routines don't have to know which kind
  283.   //  of list they're dealing with.  Keyword: polymorphism.
  284.  
  285.   BigLineList = new TQuadList(MaxLineCount);
  286.   IconicLineList = new TList(MaxIconicLineCount);
  287.   List = BigLineList;
  288.  
  289.   SetBkgndColor(TColor::Black);
  290. }
  291.  
  292. //
  293. // Dispose of the objects that this window object created.  There's
  294. //  no need to dispose the List pointer, since it will only point to
  295. //  one of these two objects which are being disposed by their
  296. //  primary pointers
  297. //
  298. TArtyWindow::~TArtyWindow()
  299. {
  300.   delete BigLineList;
  301.   delete IconicLineList;
  302. }
  303.  
  304. //
  305. // When the window is resized, scale the line list to fit the new
  306. //  window extent, or switch between full size and iconized window
  307. //  states.
  308. //
  309. void
  310. TArtyWindow::EvSize(uint sizeType, TSize& size)
  311. {
  312.   TBaseDemoWindow::EvSize(sizeType, size);
  313.  
  314.   // Force Windows to repaint the entire window region
  315.   //
  316.   Invalidate(true);
  317.  
  318.   int newXmax = size.cx;
  319.   int newYmax = size.cy;
  320.   if (sizeType == SIZE_MINIMIZED) {
  321.     if (!Iconized) {
  322.       Iconized = true;
  323.       List = IconicLineList;
  324.     }
  325.  
  326.   }
  327.   else {
  328.     if (Iconized) {
  329.       Iconized = false;
  330.       List = BigLineList;
  331.     }
  332.     newYmax -= TextHeight;  // allow room for the text at the bottom
  333.   }
  334.  
  335.   List->ScaleTo(newXmax, newYmax);  // scale the lines in the list
  336.   if (StaticControl)
  337.     StaticControl->MoveWindow(0, newYmax, newXmax, TextHeight, true);
  338. }
  339.  
  340. //
  341. // Toggle the window's Paused status.  Since the window will
  342. //  not receive mouse clicks when iconized, this will not pause the
  343. //  iconized lines display.
  344. //
  345. void
  346. TArtyWindow::EvLButtonDown(uint, TPoint&)
  347. {
  348.   Paused = !Paused;
  349. }
  350.  
  351. //
  352. // Clear the line list when the user presses the right mouse
  353. //  button.  Same comments as above on iconized windows.
  354. //
  355. void
  356. TArtyWindow::EvRButtonDown(uint, TPoint&)
  357. {
  358.   Invalidate(true);
  359.   List->ResetLines();
  360. }
  361.  
  362. //
  363. // When the window is resized, or some other window blots out part
  364. // of our client area, redraw the entire line list.
  365. //
  366. void
  367. TArtyWindow::Paint(TDC& dc, bool, TRect&)
  368. {
  369.   List->Redraw(dc);
  370. }
  371.  
  372. //
  373. // Fetch a device context, pass it to the line list object, then
  374. // release the device context back to Windows.
  375. //
  376. void
  377. TArtyWindow::TimerTick()
  378. {
  379.   if (!Paused)
  380.     List->LineTick(TClientDC(Iconized ? Parent->GetHandle() : GetHandle()));
  381. }
  382.